/**************************************************************************************************
	$Header: /pub/cvsroot/mydns/src/mydns/conf.c,v 1.6 2002/07/17 10:24:13 bboy Exp $
	conf.c: Routines to read the configuration file.

	Copyright (C) 2002  Don Moore <bboy@bboy.net>

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at Your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
**************************************************************************************************/

#include "named.h"

#include <pwd.h>
#include <grp.h>

CONF	*Conf = (CONF *)NULL;									/* Config options */
int	opt_daemon = 0;											/* Run in background? (-d, --daemon) */
char	*opt_conf = MYDNS_CONF;									/* Location of config file (-c, --conf) */
uid_t	perms_uid = 0;												/* User permissions */
gid_t	perms_gid = 0;												/* Group permissions */
time_t task_timeout;												/* Task timeout */


/* Default config values */
static CONF defConfig[] = {
	{	"-",							NULL,							"DATABASE INFORMATION",					NULL },
	{	"mysql-host",				"localhost",				"MySQL server hostname",				NULL },
	{	"mysql-user",				"user",						"MySQL username",							NULL },
	{	"mysql-password",			"password",					"MySQL password",							NULL },
	{	"database",					PACKAGE_NAME,				"MyDNS database name",					NULL },

	{	"-",							NULL,							"GENERAL OPTIONS",						NULL },

	{	"user",						"nobody",					"Run with the permissions of this user",		NULL },
	{	"group",						"nogroup",					"Run with the permisisons of this group",		NULL },
	{	"port",						"53",							"Listen on this port number",	NULL},
	{	"pidfile",					"/var/run/"PACKAGE_NAME".pid",	"Path to PID file",						NULL },
	{	"timeout",					"60",							"Number of seconds after which queries time out", NULL },
	{	"multicpu",					"1",							"Number of CPUs installed on your system",	NULL },

	{	"-",							NULL,							"ZONE CACHE OPTIONS",					NULL },

	{	"cache-size",				"4096",						"Maximum number of elements stored in the zone cache",	NULL },
	{	"cache-expire",			"300",						"Number of seconds after which cached zones expire", NULL },

	{	NULL,							NULL,							NULL }
};


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	OUTPUT_CREATE_TABLES
	Output SQL statements to create tables and exit.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void
output_create_tables(void)
{
	/* Header */
	printf(
"--
--  Table layouts for "PACKAGE_STRING" ("PACKAGE_DATE")
--  "PACKAGE_COPYRIGHT"
--
--  You might create these tables with a command like:
--
--    $ %s --create-tables | mysql -hHOST -p -uUSER DATABASE
--
--
", progname);

	/* Zone/SOA table */
	puts("
--
--  Table structure for table '"MYDNS_SOA_TABLE"' (zones of authority)
--

CREATE TABLE IF NOT EXISTS "MYDNS_SOA_TABLE" (
  id         INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  origin     CHAR(78) NOT NULL,
  ns         CHAR(255) NOT NULL,
  mbox       CHAR(255) NOT NULL,
  serial     INT UNSIGNED NOT NULL default '1',
  refresh    INT UNSIGNED NOT NULL default '28800',
  retry      INT UNSIGNED NOT NULL default '7200',
  expire     INT UNSIGNED NOT NULL default '604800',
  minimum    INT UNSIGNED NOT NULL default '86400',
  ttl        INT UNSIGNED NOT NULL default '86400',
  UNIQUE KEY (origin)
) TYPE=MyISAM;
");

	/* Resource record table */
	puts("
--
--  Table structure for table '"MYDNS_RR_TABLE"' (resource records)
--

CREATE TABLE IF NOT EXISTS "MYDNS_RR_TABLE" (
  id         INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  zone       INT UNSIGNED NOT NULL,
  name       CHAR(64) NOT NULL,
  type       ENUM('A','AAAA','CNAME','MX','NS','TXT'),
  data       CHAR(255) NOT NULL,
  aux        INT UNSIGNED NOT NULL,
  ttl        INT UNSIGNED NOT NULL default '86400',
  UNIQUE KEY rr (zone,name,type,data)
) TYPE=MyISAM;
");

	/* PTR table */
	puts("
--
--  Table structure for table '"MYDNS_PTR_TABLE"'
--

CREATE TABLE IF NOT EXISTS "MYDNS_PTR_TABLE" (
  id         INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  ip         INT UNSIGNED NOT NULL,
  name       CHAR(255) NOT NULL,
  ttl        INT UNSIGNED NOT NULL default '86400',
  UNIQUE KEY (ip)
) TYPE=MyISAM;
");
	exit(EXIT_SUCCESS);
}
/*--- output_create_tables() --------------------------------------------------------------------*/


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	DUMP_CONFIG
	Output configuration info (in a sort of config-file format).
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void
dump_config(void)
{
	time_t time_now = time(NULL);
	int len = 0, w = 0, n;
	char pair[512];
	CONF *c;

	printf("\
##
##  "MYDNS_CONF"
##  %.24s
##  %s
##
", ctime(&time_now), _("For more information, see mydns.conf(5)."));

	/* Look up description for configured variables and determine longest name/value pair length */
	for (n = 0; defConfig[n].name; n++)
	{
		char *value = conf_get(&Conf, defConfig[n].name);

		c = &defConfig[n];
		if (!value)
			value = c->value;
		if ((len = strlen(c->name) + (value ? strlen(value) : 0)) > w)
			w = len;
	}
	w += strlen(" = ");

	for (n = 0; defConfig[n].name; n++)
	{
		char *value = conf_get(&Conf, defConfig[n].name);

		c = &defConfig[n];
		if (!value)
			value = c->value;
		if (c->name[0] == '-')
			printf("\n");
		else
		{
			snprintf(pair, sizeof(pair), "%s = %s", c->name, value);
			printf("%-*.*s\t# %s\n", w, w, pair, c->desc);
		}
	}
	printf("\n");
}
/*--- dump_config() -----------------------------------------------------------------------------*/


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	LOAD_CONFIG
	Load the configuration file.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void
load_config(void)
{
	int n;
	struct passwd *pwd = NULL;
	struct group *grp = NULL;

	/* Load config */
	conf_load(&Conf, opt_conf);

	/* Set defaults */
	for (n = 0; defConfig[n].name; n++)
	{
		if (defConfig[n].name[0] == '-')
			continue;
		if (!conf_get(&Conf, defConfig[n].name))
			conf_set(&Conf, defConfig[n].name, defConfig[n].value);
	}

#if HAVE_GETPWUID
	/* Set default for MySQL username to real username if none was provided */
	if (!conf_get(&Conf, "mysql-user"))
	{
		struct passwd *pwd;
		if ((pwd = getpwuid(getuid())) && pwd->pw_name)
		{
			conf_set(&Conf, "mysql-user", pwd->pw_name);
			memset(pwd, 0, sizeof(struct passwd));
		}
	}
#endif

	/* Load user/group perms */
	if (!(pwd = getpwnam(conf_get(&Conf, "user"))))
		Err(_("error loading uid for user `%s'"), conf_get(&Conf, "user"));
	perms_uid = pwd->pw_uid;
	perms_gid = pwd->pw_gid;
	memset(pwd, 0, sizeof(struct passwd));

	if (!(grp = getgrnam(conf_get(&Conf, "group"))) && !(grp = getgrnam("nobody")))
	{
		Warnx(_("error loading gid for group `%s'"), conf_get(&Conf, "group"));
		Warnx(_("using gid %u from user `%s'"), perms_gid, conf_get(&Conf, "user"));
	}
	else
	{
		perms_gid = grp->gr_gid;
		memset(grp, 0, sizeof(struct group));
	}

	/* Set task timeout */
	task_timeout = atou(conf_get(&Conf, "timeout"));
}
/*--- load_config() -----------------------------------------------------------------------------*/

/* vi:set ts=3: */
/* NEED_PO */
